﻿
using Dapper;
using HBase;
using Net.http;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Transactions;

namespace hCommand
{
    /**
   *┌────────────────────────────────────────────────┐
   *│　描    述：Component                                                    
   *│　作    者：sgj                                              
   *│　版    本：1.0                                              
   *│　创建时间：2020/9/2 11:28:16                        
   *└────────────────────────────────────────────────┘
   **/
    public  class InLocEngine<CS> : AbsTaskEngine where CS : AbsCoreStock {
        public String boxCode;
        public int stn;
       
        protected override TransRes Execute(IDbConnection conn ,IDbTransaction tran) {
            List<CoreTask> coreTaskList = checkCodeInWork(conn ,tran);
            if( coreTaskList.Count == 1 ) {
                if (canContinue()) {
                    return continueTask(conn, tran, coreTaskList[0]);
                } else {
                    return new TransRes(true, "contiue forbidden!");
                }
             
                 ;
            } else if( coreTaskList.Count > 1 ) {

                return new TransRes(true ,boxCode + "at" + stn + "working 不能入库!");
            }
            before(conn ,tran);
            CS cs = getStock(conn ,tran);

            if (cs.status == (int)StockStatus.盘库中) {
                return new TransRes(boxCode + "at" + stn + "盘库中，盘库任务已经结束，不能重复入库" );
            }
            if( cs.status != (int)StockStatus.库外) {
                return new TransRes(boxCode + "at" + stn + "状态不能入库!" + cs.status);
            }
            // 可能原来入库站台，与正式入库口不一直。
            cs.locId = stn;
            long stockId = cs.id;
           
            CoreWhLoc loc = selectLoc(conn ,tran , cs);
            if( loc == null ) {

                CoreClassify area = conn.GetById<CoreClassify>(cs.classifyId, tran);
                if (area == null) { 
                    return new TransRes(boxCode +  "物料分类不存在"+ cs.classifyId);
                } else {
                    return new TransRes(boxCode + area.name + "无可用货位");
                } 
            }
            long raly = getRaly(conn, tran, cs, loc);

            String waveNo = getWaveNo(conn, tran, cs, loc);
            createInTask(cs.deepDiff, cs ,( int ) loc.id ,conn ,tran, raly+"", waveNo);
      
            return afterIntask(conn ,tran ,cs ,   loc);
        }
        TransRes continueTask(IDbConnection conn, IDbTransaction trans, CoreTask ct) {
            String sql = "select * from Core_task_param where task_id=@taskId  and type={0} and status <= {1}  and status>={2}";

            sql= HUtil.formatInt(sql, TaskParamType.托盘搬运, CoreTaskParamStatus.执行结束, CoreTaskParamStatus.可以接收任务);
            List<CoreTaskParam> list = conn.Query<CoreTaskParam>(sql, new { taskId = ct.id }, trans).ToList();
            if (list.Count > 0) {
                return doContinue( conn,  trans,  ct,  list);
            }
            TransRes res = humanCanContinue(conn, trans, ct);
            if (res.s) {
                int des = ct.src;
                moveCoreTaskParam(conn, trans, "", ct.id, stn, des, "");
                CS cs = conn.GetById<CS>(ct.stockId, trans);
                UpdataWhLoc(conn, trans, des, cs.deepDiff );
            }
            return res;
        }

        virtual public TransRes doContinue(IDbConnection conn, IDbTransaction trans, CoreTask ct, List<CoreTaskParam> list) {
            return new TransRes();
        }
        virtual public bool canContinue() {
            return false;
        }

        public virtual TransRes humanCanContinue(IDbConnection conn, IDbTransaction trans, CoreTask ct) {
            CS cs = conn.GetById<CS>(ct.stockId, trans);
            if (cs.status == (int)StockStatus.盘库中) {
                if (cs.locId == ct.src) {
                    return new TransRes(cs.boxCode + "已回到货位");
                }

                CoreWhLoc loc = conn.GetById<CoreWhLoc>(ct.src, trans);
                if (loc == null) {
                    return new TransRes(ct.src + "货位状态不存在");
                }
                if (loc.type == 2) {
                    return checkDouble(conn, trans, ct, loc);
                }
                return new TransRes(); 
            } else {
                return   withOutPk(conn, trans, ct); 
            }
          
        }

        public virtual TransRes withOutPk(IDbConnection conn, IDbTransaction trans, CoreTask ct) {
            
            return new TransRes(boxCode + "不可增加路径");
        }



        TransRes checkDouble(IDbConnection conn, IDbTransaction trans, CoreTask ct, CoreWhLoc loc) {

            if (loc.deepIndex > 1) {
                CoreWhLoc loc1 = conn.GetById<CoreWhLoc>(ct.src - 1, trans);
                if (loc1.countStock > 0) {
                    if (loc1.countOutin == 1) {
                        if (chechShallow(conn, trans, (int)loc1.id)) {
                            return new TransRes();
                        } else {
                            return new TransRes(loc1.id + "浅货位有任务在执行" + boxCode);
                        }

                    }
                    return new TransRes(loc1.id + "货位状态异常" + boxCode);
                }  
            } else if (loc.deepIndex == 1) {
                CoreWhLoc deepLoc = conn.GetById<CoreWhLoc>(ct.src + 1, trans);
                if (deepLoc == null || deepLoc.deepIndex == 1 || deepLoc.scr != loc.scr) {
                    return new TransRes();
                }
                if (deepLoc.countStock == 0) {
                    return new TransRes(boxCode + "深货位空闲");
                }
                if (deepLoc.countOut == 1) {
                    return new TransRes(boxCode + "深货位出库中");
                }
                if (deepLoc.countIn == 1) {
                    return new TransRes(boxCode + "深货位入库中");
                }
                if (deepLoc.countOutin == 1) {
                  int backCount=  pkBackCount(conn, trans, ct, deepLoc);
                    if (backCount == 0) {
                        return new TransRes(boxCode + "深货盘"+ deepLoc .id+ "库搬运未完成");
                    }
                }
            } 
            return new TransRes();

        }

        protected virtual int pkBackCount(IDbConnection conn, IDbTransaction trans, CoreTask ct, CoreWhLoc deeploc) {
            String sql = " SELECT count(*) FROM core_task  t join core_task_param p ON t.id = p.task_Id "
            + " where t.status = 2  and p.des = @id  ";
            int count = conn.QueryUnique<int>(sql, deeploc, trans);//浅货位有任务，但是没有动的数量

            return count;

        }
        virtual protected bool chechShallow(IDbConnection conn, IDbTransaction trans, int loc) {
            String sql = " SELECT count(*) FROM core_task  t join core_task_param p ON t.id = p.task_Id "
                + " where t.status = 2  and t.src = @loc and ( p.c_stn=  @loc  or p.des=@loc)";
            int count = conn.QueryUnique<int>(sql, new { loc }, trans);//浅货位有任务，但是没有动的数量

            int remainCount = conn.QueryUnique<int>("SELECT Count_stock-count_in-Count_out-count_outin FROM core_wh_loc  where id=@loc", new { loc }, trans);
            return count + remainCount == 0;

        }

        protected virtual String getWaveNo(IDbConnection conn, IDbTransaction trans, CS cs, CoreWhLoc loc) {
            return "";
        }
        protected virtual long getRaly(IDbConnection conn, IDbTransaction trans, CS cs, CoreWhLoc loc) {
            return 0;
        }
      
        protected virtual TransRes afterIntask(IDbConnection conn ,IDbTransaction trans ,CS cs  ,CoreWhLoc loc) {
            return new TransRes();
        }
        protected virtual void before(IDbConnection connection ,IDbTransaction transaction) {
        }

        protected virtual List<CoreTask> checkCodeInWork(IDbConnection connection ,IDbTransaction transaction) {
            string sql = "select * from Core_Task where  status <9 and  status>0 ";

            if( !String.IsNullOrWhiteSpace(boxCode) ) {
                sql += "  and box_Code=@boxCode  ";
            } else {
                sql += "  and src =  " + stn;
            }
            List<CoreTask> coreTaskList = connection.Query<CoreTask>(sql ,new {
                boxCode
            } ,transaction).ToList();
            return coreTaskList;
        }

        public virtual CS getStock(IDbConnection Connection ,IDbTransaction transaction) {
            string sql = @"select * from Core_stock where  status >={0} and status<={1}   and box_Code=@boxCode  ";
            sql = String.Format(sql,(int)StockStatus.库外 ,(int)StockStatus.库存);
            List<CS> stockList = Connection.Query<CS>(sql ,new {
                boxCode
            } ,transaction).ToList();
            if( stockList.Count == 0 ) {
                String info = boxCode + "没有库位异常stock!";
                throw new Exception(info);
            }
            if( stockList.Count > 1 ) {
                String info = boxCode + "重复的库位异常stock!";
                throw new Exception(info);
            }
            CS cs = stockList[0];
            return cs;
        }
    }
}
